729142
@@ -32,6 +32,8 @@
import static org.wildfly.extension.elytron.Capabilities.SECURITY_FACTORY_CREDEN
 import static org.wildfly.extension.elytron.ElytronExtension.asStringIfDefined;
 import static org.wildfly.extension.elytron.ElytronExtension.getRequiredService;
 
+import org.wildfly.security.http.HttpConstants;
+
 import java.security.Principal;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -81,6 +83,7 @@
import org.wildfly.security.auth.server.SaslAuthenticationFactory;
 import org.wildfly.security.auth.server.SecurityDomain;
 import org.wildfly.security.http.HttpServerAuthenticationMechanismFactory;
 import org.wildfly.security.http.util.FilterServerMechanismFactory;
+import org.wildfly.security.http.util.SortedServerMechanismFactory;
 import org.wildfly.security.sasl.util.FilterMechanismSaslServerFactory;
 import org.wildfly.security.sasl.util.SaslMechanismInformation;
 import org.wildfly.security.sasl.util.SortedMechanismSaslServerFactory;
@@ -390,6 +393,22 @@
class AuthenticationFactoryDefinitions {
                     // filter non-configured mechanisms out (when we are sure they are not configured)
                     if ( ! supportedMechanisms.isEmpty()) {
                         serverFactory = new FilterServerMechanismFactory(serverFactory, true, supportedMechanisms);
+
+                        final String[] mechanisms = supportedMechanisms.toArray(new String[supportedMechanisms.size()]);
+                        serverFactory = new SortedServerMechanismFactory(serverFactory, (a, b) -> {
+                            for (String definedMech : mechanisms) {
+                                if (a.equals(definedMech)) {
+                                    return -1;
+                                } else if (b.equals(definedMech)) {
+                                    return 1;
+                                }
+                            }
+
+                            // The filter should have ensured only mechanism names we know are compared.
+                            return 0;
+                        });
+                    } else {
+                        serverFactory = new SortedServerMechanismFactory(serverFactory, AuthenticationFactoryDefinitions::compareHttp);
                     }
 
                     HttpAuthenticationFactory.Builder builder = HttpAuthenticationFactory.builder()
@@ -457,19 +476,17 @@
class AuthenticationFactoryDefinitions {
                 return () -> {
                     SaslServerFactory serverFactory = saslServerFactoryInjector.getValue();
 
-                    // filter non-configured mechanisms out (when we are sure they are not configured)
-                    if ( ! supportedMechanisms.isEmpty()) {
-                        serverFactory = new FilterMechanismSaslServerFactory(serverFactory, true, supportedMechanisms);
-                    }
-
                     if (! supportedMechanisms.isEmpty()) {
+                        // filter non-configured mechanisms out (when we are sure they are not configured)
+                        serverFactory = new FilterMechanismSaslServerFactory(serverFactory, true, supportedMechanisms);
                         // sort mechanisms using the configured order
                         serverFactory = new SortedMechanismSaslServerFactory(serverFactory, supportedMechanisms.toArray(new String[supportedMechanisms.size()]));
                     } else {
                         // no mechanisms were configured, sort mechanisms by strength
-                        serverFactory = new SortedMechanismSaslServerFactory(serverFactory, AuthenticationFactoryDefinitions::compare);
+                        serverFactory = new SortedMechanismSaslServerFactory(serverFactory, AuthenticationFactoryDefinitions::compareSasl);
                     }
 
+
                     SaslAuthenticationFactory.Builder builder = SaslAuthenticationFactory.builder()
                             .setSecurityDomain(securityDomainInjector.getValue())
                             .setFactory(serverFactory);
@@ -498,11 +515,11 @@
class AuthenticationFactoryDefinitions {
         return  mechanismNames.toArray(new String[mechanismNames.size()]);
     }
 
-    private static int compare(String nameOne, String nameTwo) {
-        return toPriority(nameTwo) - toPriority(nameOne);
+    private static int compareSasl(String nameOne, String nameTwo) {
+        return toPrioritySasl(nameTwo) - toPrioritySasl(nameOne);
     }
 
-    private static int toPriority(String name) {
+    private static int toPrioritySasl(String name) {
         switch (name) {
             case SaslMechanismInformation.Names.EXTERNAL:
                 return 30;
@@ -519,6 +536,26 @@
class AuthenticationFactoryDefinitions {
         }
     }
 
+    private static int compareHttp(String nameOne, String nameTwo) {
+        return toPriorityHttp(nameTwo) - toPriorityHttp(nameOne);
+    }
+
+    private static int toPriorityHttp(String name) {
+        switch (name) {
+            case HttpConstants.CLIENT_CERT_NAME:
+                return 30;
+            case HttpConstants.SPNEGO_NAME:
+                return 20;
+            case HttpConstants.BEARER_TOKEN:
+                return 10;
+            case HttpConstants.BASIC_NAME:
+                // i.e. Any hashed username / password mechs are preferred.
+                return -10;
+            default:
+                return 0;
+        }
+    }
+
     private static class ResolvedMechanismRealmConfiguration {
         final InjectedValue<PrincipalTransformer> preRealmPrincipalTranformer = new InjectedValue<>();
         final InjectedValue<PrincipalTransformer> postRealmPrincipalTransformer = new InjectedValue<>();
